<template>
  <div class="evidenceCatalogTree_box" :id="id">

    <div class="evidence_catalog_tree_box" :class="{recycle_bin_expand:recycleBinExpand}">
      <div class="search_box" :style="skin.style.EvidenceCatalogTree_search_box">
        <input class="search_input" placeholder="关键字检索" v-model="filterText"/>
      </div>

      <u-tree
        ref="evidenceTree"
        class="evidenceCatalogTree"
        :data="evidenceCatalogTreeData"
        :show-checkbox="true"
        node-key='id'
        :expand-on-click-node="true"
        :filter-node-method="filterNode"
        :default-expanded-keys="defaultExpandedKeys"
        @node-click="nodeClick"
        :render-content="renderContent"
        :props="{label:'alias',children:'children'}"
      ></u-tree>
    </div>

    <div class="evidence_catalog_recycle_bin" :class="{recycle_bin_expand:recycleBinExpand}">
      <div class="title" @click="recycleBinExpand=!recycleBinExpand">
        <div class="title_text">
          回收站({{evidenceCatalogRecycleBinData.length}})
        </div>
        <div class="title_btn"></div>
      </div>
      <div class="evidence_catalog_recycle_bin_tool">
        <el-checkbox :indeterminate="isIndeterminate" v-model="toggleAll" label="全选"></el-checkbox>
        <div class="btns">
          <div class="btn" @click="clearRecycleBinData()" v-show="toggleAll||isIndeterminate">一键清除</div>
        </div>
      </div>
      <div class="content">
        <div class="content_item" v-for="item in evidenceCatalogRecycleBinData">
          <div class="content_item_title">
            <div class="date nowrap">
              <el-checkbox v-model="checkedList[item.id]" :label="item.cjsj"></el-checkbox>
            </div>
            <div class="btns">
              <div class="btn" @click="clearRecycleBinData(item)">清除</div>
              <div class="btn" @click="restoreRecycleBinData(item)">还原</div>
            </div>
          </div>
          <el-tree class="evidenceCatalogRecycleBinTree"
                   node-key='id'
                   :props="{label:'alias'}"
                   ref="evidenceCatalogRecycleBinTree"
                   :data="item.nr">
          </el-tree>
        </div>
        <div class="nodata" v-if="!evidenceCatalogRecycleBinData.length"></div>
      </div>
    </div>

    <pre-zjcl class="prezjcl" :inline="false" ref="PreZjcl"></pre-zjcl>
    <div ref="cursor" class="cursor_div">
      <div ref="cursor_img" class="cursor_img"></div>
      <div class="cursor_text nowrap">{{cursor_text}}</div>
    </div>

    <vmodal :modalshow="modalshow" modaltitle="选择父节点" :closeonclickmodal="false"
            :styleobj="{width: '300px',height: '437px'}" @hide="modalshow=false">
      <div slot="modal" style="width:100%;height:100%;background-color: white">
        <div style="width:100%;height:calc(100% - 50px);overflow: auto;">
          <el-tree ref="catalogMLTree" highlight-current render-after-expand node-key='id' default-expand-all
                   :data="catalogML" :props="catalogProps" style="width:100%">
          </el-tree>
        </div>
        <div style="text-align: right;height: 50px">
          <el-button style="margin:5px 10px 0 0" size="small" type="plain" @click="modalshow=false">取消
          </el-button>
          <el-button style="margin:5px 10px 0 0" size="small" type="primary"
                     @click="restoreRecycleBinData(recycleBinData,modalshow)">确认
          </el-button>
        </div>
      </div>
    </vmodal>

  </div>
</template>

<script>
  /* eslint-disable */
  import {mapState, mapActions} from 'vuex'
  import L from '../common/localStore'
  import events from '../common/typeEvents'
  import {action} from '../common/quantity'
  import actions from '../common/typeActions'
  import commonServer from '../server/common/commonServer'

  import evidenceCatalogTree from '../config/evidenceCatalogTree'

  let remote = {}
  try {
    remote = require('electron').remote
  } catch (e) {

  }

  const {
    util: {
      insertText,
      recursionUpdateIdAndPid,
      getPrePushNodes,
      getRandomId,
      getCatalogML,
      getTreeNodes,
      getBase64
    },
    CMD: {openDirOrFile}
  } = require('../util')

  const uuid = require('uuid/v4')
  const path = require('path')
  const fs = require('fs')
  const skin = require('../config/skin')

  export default {
    name: 'evidenceCatalogTree',
    data () {
      return {
        dataField: {
          textField: 'alias', // 展示的文字
          valueField: 'id', // id
          keyField: 'id', // id
          parentKeyField: 'pid' // 父节点的id
        },
        treeData: [],

        defaultExpandedKeys: [],
        evidenceCatalogTreeData: [],
        filterText: '',
        currentNode: {},
        isRename: false,
        id: getRandomId(),
        skin: skin[skin.useSkin],
        lastCheckedNode: {},
        pressShiftKey: false,
        pressCtrlKey: false,

        recycleBinExpand: false,
        modalshow: false,
        catalogProps: {
          children: 'children',
          label: 'alias'
        },
        cursor_text: '',
        recycleBinData: '',
        isIndeterminate: false,
        catalogML: [],
        checkedList: {},
        copyCatalog: null,
        editID: ''
      }
    },
    computed: {
      ...mapState({
        // evidenceCatalogTreeData: state => JSON.parse(JSON.stringify(state.preplan.evidenceCatalogTreeData)),
        dossierDataSource: state => state.appearCourt.dossierDataSource,
        docDossierDataSource: state => state.appearCourt.docDossierDataSource,
        userInfo: state => state.mainPage.userInfo,
        casePath: state => state.appearCourt.casePath,
        caseInfo: state => state.appearCourt.caseInfo,
        slide: state => state.slideEditor.slide,
        DefaultBackground: state => state.slideEditor.DefaultBackground,
        isMergeDir: state => state.common.preplanOptions.isMergeDir,
        tempData: state => state.common.tempData,
        catalogTemplate: state => state.preplan.catalogTemplate,
        evidenceCatalog: state => state.preplan.evidenceCatalog,
        evidenceCatalogRecycleBinData: state => JSON.parse(JSON.stringify(state.preplan.evidenceCatalogRecycleBinData))
      }),
      toggleAll: {
        get () {
          let hasUnchecked = false
          let hasChecked = false

          for (let item of this.evidenceCatalogRecycleBinData) {
            if (this.checkedList[item.id]) { // 如果选中
              hasChecked = true// 标记存在已选中
            }
            if (!this.checkedList[item.id]) { // 如果未选中
              hasUnchecked = true// 标记未选中
            }
            if (hasChecked && hasUnchecked) { // 如果均存在
              this.isIndeterminate = true
              break
            }
          }
          this.isIndeterminate = hasChecked && hasUnchecked

          return (hasChecked || hasUnchecked) && !hasUnchecked
        },
        set (vulue) {
          this.evidenceCatalogRecycleBinData.forEach(item => {
            this.$set(this.checkedList, item.id, vulue)
          })
        }
      }
    },
    watch: {
      filterText (newVal, oldVal) {
        this.$refs.evidenceTree.filter(newVal)
      },
      slide (n, o) {
        let tree = this.$refs.evidenceTree
        if (!tree) return
        let node = n ? tree.getNode(n.id) : null
        if (!node) return
        this.expandNode(n.id)
        tree.setCurrentNode(node.data)
        let el = document.querySelector(`#${this.id} .node_${n.id}`)
        this.$nextTick(() => {
          if (el) {
            el.scrollIntoView({
              behavior: 'smooth',
              block: 'nearest',
              inline: 'nearest'
            })
          }
        })
      }
    },
    async mounted () {
      await evidenceCatalogTree.init()
      this.evidenceCatalogTreeData = evidenceCatalogTree.state.evidenceCatalogTreeData
      this.evidenceCatalogTreeData.forEach(item => {
        this.defaultExpandedKeys.push(item.id)
      })

      // 阅卷加入证据
      this.$eventBus.$on('ADD_FILES_INTO_CATALOG', async (obj = {}) => {
        if (!('dossiers' in obj)) {
          obj = {node: obj.node, dossiers: JSON.stringify([obj.dossier])}
        }

        let nodes = JSON.parse(obj.dossiers)

        if (this.isMergeDir) {
          nodes.forEach(item => {
            if (item.FileType === 'dir') return
            let pnode = nodes.find(_item => item.NodeParentID === _item.NodeID)
            if (!pnode) return
            if (pnode.FileType !== 'dir') return
            item.MLXSMC = `${pnode.MLXSMC}(${item.MLXSMC})`
          })
          nodes = nodes.filter(item => item.FileType !== 'dir')
        }
        nodes.forEach(x => {
          x.style = this.DefaultBackground
          x.template = this.$store.getters.defaultTemplate
        })
        let prePush = getPrePushNodes(nodes)

        for (let i = 0; i < prePush.length; i++) {
          let _node = prePush[i]
          _node.pid = obj.node.id
          this.append(_node, obj.node)
        }

        await this.synch()
        this.setSelectedNode(obj.node.id)
        this.$message({message: '添加成功', type: 'success'})

        this.$emit('clear-checked', 'juanzong')
      })
      // 修改节点风格和版式
      this.$eventBus.$on(
        events.SlideEditor.SlideStyleAndTemplateChanged,
        async obj => {
          let tree = this.$refs.evidenceTree
          if (!tree) return
          let node = tree.getNode(obj.id)
          if (!node) return
          node.data.style = obj.sid
          node.data.template = obj.tid
          await this.synch()
          this.expandNode(node.data.id, false)
          tree.setCurrentNode(node.data)
        }
      )

      this.$eventBus.$on('keyup', ev => {
        if (ev.key === 'Shift') {
          this.pressShiftKey = false
        } else if (ev.key === 'Control') this.pressCtrlKey = false
      })
      this.$eventBus.$on('keydown', ev => {
        if (ev.key === 'Shift') {
          this.pressShiftKey = true
        } else if (ev.key === 'Control') this.pressCtrlKey = true
      })
    },
    methods: {
      ...mapActions({
        initSlide: actions.SLIDEEDITOR.InitSlide,
        setSlideTitle: actions.SLIDEEDITOR.SetSlideTitle
      }),
      async restoreRecycleBinData (recycleBinData, modalshow) {
        try {
          this.loadStatus({loading: true, loadingText: '处理中...'})
          let nodeId = ''
          if (modalshow) {
            let _node = this.$refs.catalogMLTree.getCurrentNode()
            if (!_node) return this.$alert('请选择目录节点')
            nodeId = _node.id
            this.modalshow = false
          } else {
            nodeId = recycleBinData.nr[0].pid
          }
          let tree = this.$refs.evidenceTree
          let node = tree.getNode(nodeId)
          if (node) {
            recycleBinData.nr[0].pid = nodeId
            this.append(recycleBinData.nr[0], node)
          } else {
            await this.$confirm('没有找到父节点，是否添加到别的节点中？', '提示', {confirmButtonText: '是', cancelButtonText: '否'})
            this.recycleBinData = recycleBinData

            this.catalogML = evidenceCatalogTree.getCatalogML()
            return (this.modalshow = true)
          }
          if (this.recycleBinData) this.recycleBinData = ''
          await this.$store.dispatch(action.preplan.clearRecycleBinData, recycleBinData)
          this.synch()
        } catch (e) {
          if (e !== 'cancel') this.$alert(`失败原因：${e.message}`, '还原失败', {type: 'error'})
        } finally {
          this.loadStatus()
        }
      },
      async clearRecycleBinData (recycleBinData) {
        try {
          await this.$confirm('此操作不可恢复，是否继续？', '提示', {cancelButtonText: '否', confirmButtonText: '是'})
          this.loadStatus({loading: true, loadingText: '处理中...'})
          if (recycleBinData) {
            await this.$store.dispatch(action.preplan.clearRecycleBinData, recycleBinData)
          } else {
            for (let item of this.evidenceCatalogRecycleBinData) {
              if (this.checkedList[item.id]) {
                await this.$store.dispatch(action.preplan.clearRecycleBinData, item)
                delete this.checkedList[item.id]
              }
            }
          }
        } catch (e) {
          if (e !== 'cancel') this.$alert(`失败原因：${e.message}`, '清除失败', {type: 'error'})
        } finally {
          this.loadStatus()
        }
      },
      async TBZHGSSJ () {
        try {
          await this.$confirm('此操作会覆盖当前示证目录数据，是否继续？', '提示', {confirmButtonText: '是', cancelButtonText: '否'})
          this.loadStatus({loading: true, loadingText: '数据同步中...'})

          let treeDataSource = await this.$api.post.DownloadEvidenceCatalog(this.caseInfo.BMSAH)
          if (!treeDataSource) return this.$message({message: '同步失败：未获取到阅卷辅助数据', type: 'error'})
          treeDataSource = JSON.parse(treeDataSource)
          // if (typeof treeDataSource.data === 'string') {
          //   treeDataSource = JSON.parse(treeDataSource.data)
          // } else {
          //   treeDataSource = treeDataSource.data
          // }

          // if (!treeDataSource) return this.$alert('示证目录数据与案件分析相同！', '提示')

          this.evidenceCatalogTreeData.splice(0, this.evidenceCatalogTreeData.length)
          treeDataSource.forEach(item => {
            this.evidenceCatalogTreeData.push(item)
          })

          this.synch()
        } catch (e) {
          if (e !== 'cancel') this.$alert(`失败原因：${e.message}`, '同步失败', {type: 'error'})
        } finally {
          this.loadStatus()
        }
      },
      clearSlideEditor (id) {
        if ((this.slide && this.slide.id === id) || !id) this.initSlide()
      },
      async addRecycleBinData (nodes) {
        nodes = nodes.filter(node => !nodes.find(item => item.id === node.pid))

        console.log('addRecycleBinData=====================', nodes)

        for (let i = 0; i < nodes.length; i++) {
          await this.$store.dispatch(action.preplan.addRecycleBinData, nodes[i])
        }
      },
      async synch () {
        await evidenceCatalogTree.synch()
      },
      async preView () {
        let node = this.currentNode.data
        console.log(node.fileID)
        let pdf = await commonServer.getPDFFileByID(node.fileID)
        if (!pdf) return this.$alert('预览失败', '错误', {type: 'error'})
        if (/mp3|mp4/i.test(node.suffix)) {
          // const {dir, name} = path.parse(this.casePath);
          let dir = path.dirname(this.casePath)
          let name = path.basename(this.casePath)
          let pathStr = path.resolve(dir, name, pdf)
          // if (!process.browser && !fs.existsSync(pathStr)) return this.$alert(`文件【${pathStr}】不存在！`, '找不到文件', {type: 'error'})
          this.$refs.PreZjcl.show(pathStr)
        } else if (/docx?|pdf|jpe?g|png|bmp|gif/i.test(node.suffix)) {
          this.$refs.PreZjcl.show(pdf)
        }
      },
      paste (ev) {
        ev.preventDefault()
        ev.stopPropagation()
        let str = ev.clipboardData.getData('Text')
        insertText(str)
      },
      async saveNode (ev, data, node) {
        if (ev.type === 'keydown') {
          if (ev.keyCode === 13) {
            ev.preventDefault()
            ev.target.blur()
          }
          return
        }

        this.isRename = false
        this.editID = ''
        if (data.alias === ev.target.value) return
        data.alias = ev.target.value

        await this.synch()
        if ((data.type.toString() === '1' && data.fileID) || data.type.toString() === '2') {
          this.setSlideTitle({id: data.id, text: data.alias})
        }
        this.expandNode(data.id)
      },
      renameNode (event = {}, data, node) {
        if (node && node.level === 1) return
        data = data || this.currentNode.data
        if (this.ctrlKey) return
        this.editID = data.id
        this.$nextTick(() => {
          let el = document.getElementById(data.id + '_span')
          el.focus()
          el.select()
          this.isRename = true
        })
      },
      copyNode () {
        this.copyCatalog = JSON.parse(JSON.stringify(this.currentNode.data))
      },
      pasteNode () {
        let catalog = this.clearNodeState(this.copyCatalog)
        this.append(catalog, this.currentNode.data)
        this.synch()
      },
      clearNodeState (node, pid) {
        let catalogs = []

        if (!Array.isArray(node)) {
          if (Number.parseInt(node.type) !== 0) return
          catalogs = {...node, id: uuid(), pid}
          if (node.children && node.children.length) catalogs.children = this.clearNodeState(node.children, catalogs.id)
        } else {
          for (let i = 0; i < node.length; i++) {
            if (node[i].type !== 0) continue
            let catalog = {...node[i], id: uuid(), pid}

            catalog.children = node[i].children && node[i].children.length ? this.clearNodeState(node[i].children, catalog.id) : []
            catalogs.push(catalog)
          }
        }
        return catalogs
      },
      addSubNode () {
        let subNode = {
          id: uuid(),
          pid: this.currentNode.data.id,
          name: '新建子目录',
          type: 0,
          alias: '新建子目录',
          suffix: '',
          stream: [],
          comment: '',
          order: 3,
          show: true,
          fileType: '',
          fileID: '',
          style: '',
          template: '',
          children: []
        }
        this.append(subNode, this.currentNode.data)
        this.synch()
      },
      addBlankPage () {
        let isDir = Number(this.currentNode.data.type) === 0
        let data = isDir
          ? this.currentNode.data
          : this.currentNode.node.parent.data
        if (!data.children) this.$set(data, 'children', [])
        if (isDir) {
          this.append({
            id: uuid(),
            pid: this.currentNode.data.id,
            name: '空白页',
            type: 1,
            alias: '空白页',
            suffix: '',
            stream: '',
            comment: '',
            order: 1,
            show: true,
            fileType: '',
            fileID: '',
            style: '',
            template: ''
          }, data)
        }
        this.synch()
      },
      async addFiles () {
        let preSave = []
        try {
          // if (process.browser) {
            let formData = new FormData()
            formData.append('dbPath', this.$store.state.appearCourt.casePath)
            for (let i = 0; i < event.target.files.length; i++) {
              formData.append('files', event.target.files[i])
            }
            let uploadFiles = await this.$api.post.uploadFiles(formData)

            this.addFileNodes(uploadFiles)
          // } else {
          //   let win = remote.BrowserWindow.getFocusedWindow()
          //   let allFilters = [
          //     {
          //       name: '文档',
          //       extensions: ['doc', 'docx', 'pdf']
          //     },
          //     {
          //       name: '图片',
          //       extensions: ['png', 'jpg', 'bmp']
          //     },
          //     {
          //       name: '音频',
          //       extensions: ['mp3']
          //     },
          //     {
          //       name: '视频',
          //       extensions: ['mp4']
          //     }]
          //
          //   let filters = allFilters.reduce((previousValue, currentValue) => {
          //     return {
          //       name: '所有支持格式',
          //       extensions: [...previousValue.extensions, ...currentValue.extensions]
          //     }
          //   })
          //   allFilters.unshift(filters)
          //
          //   let rs = await remote.dialog.showOpenDialog(win, {
          //     properties: ['openFile', 'showHiddenFiles', 'multiSelections'],
          //     filters: allFilters
          //   })
          //
          //   if (!rs) return
          //
          //   this.loadStatus({loading: true, loadingText: '添加文件中，请稍候...'})
          //   preSave = await this.$store.dispatch(action.preplan.AddExternalFiles, rs)
          //   this.addFileNodes(preSave)
          // }
        } catch (e) {
          console.log(e)
        } finally {
          this.loadStatus({loading: false})
        }
      },
      addFileNodes (preSave) {
        for (let item of preSave) {
          if (item.ErrorMessage) {
            this.$alert(`【${item.FilePath}】添加失败，失败原因：${item.ErrorMessage}`, '提示', {type: 'warning'})
            continue
          }
          let ext = path.extname(item.FilePath)
          let base = path.basename(item.FilePath.replace(/\\/g, '/'))
          let obj = {
            id: uuid(),
            pid: this.currentNode.data.id,
            name: base,
            type: 1,
            alias: base,
            suffix: ext.toUpperCase(),
            stream: [item.ID],
            comment: '',
            order: 1,
            show: true,
            fileType: /mp4/i.test(ext) ? 'MEDIA' : /mp3/i.test(ext) ? 'AUDIO' : 'IMAGE', // IMAGE
            fileID: item.ID,
            style: this.DefaultBackground,
            template: this.$store.getters.defaultTemplate
          }
          this.append(obj, this.currentNode.data)
        }
        this.synch()
      },
      insertCatalog () {
        this.$parent.$parent.$refs.docView.insertCatalog()
      },
      recurExpand (node) {
        node.expand()
        if (node.childNodes) {
          for (let _node of node.childNodes) {
            this.recurExpand(_node)
          }
        }
      },
      recurCollapse (node) {
        if (node.childNodes) {
          for (let _node of node.childNodes) {
            this.recurCollapse(_node)
          }
        }
        node.collapse()
      },
      expandAll () {
        this.recurExpand(this.currentNode.node)
      },
      collapseAll () {
        this.recurCollapse(this.currentNode.node)
      },
      addPage () {
        if (!this.currentNode.data.children) {
          this.$set(this.currentNode.data, 'children', [])
        }

        let id = uuid()
        let sid = this.$store.state.preplan.defaultChapterTemplate
        let tid = this.$store.getters.template(sid)

        tid = tid.length ? tid[0].id : ''
        this.append({
          id: id,
          pid: this.currentNode.data.id,
          name: '默认标题',
          type: 2,
          alias: '默认标题',
          suffix: '',
          stream: [],
          comment: '',
          order: 1,
          show: true,
          fileType: 'IMAGE',
          fileID: '150312fd-6e0d-4953-867b-70730b85c7f6',
          style: sid,
          template: tid
        }, this.currentNode.data)
        // this.currentNode.data.children.push()
        this.synch()
      },
      async initCatalogData () {
        try {
          await this.$confirm(
            '初始化将会删除当前示证目录所有数据，是否继续？',
            '提示',
            {
              confirmButtonText: '是',
              cancelButtonText: '否'
            }
          )
          evidenceCatalogTree.reset()
          await this.synch()
          this.clearSlideEditor()
          // this.$parent.$parent.$refs.docView.refresh();
        } catch (e) {
          console.error(e)
        }
      },
      async saveTemplate () {
        let {value} = await this.$prompt('请输入模板名称', '提示', {
          inputPattern: /[^ ]+/,
          inputErrorMessage: '模板名称不能为空'
        })

        // 获取所有的树文件夹
        let catalogML = getCatalogML(
          JSON.parse(JSON.stringify(this.evidenceCatalogTreeData))
        )

        L.LocalStore.saveTemplate(catalogML[0].children, value)
        this.$store.dispatch(action.preplan.getCatalogTemplate)
        this.$message({type: 'success', message: `模板保存成功: ${value}`})
      },
      moveUp () {
        let children =
          this.currentNode.node.parent.data.children ||
          this.currentNode.node.parent.data
        let index = children.findIndex(x => x.id === this.currentNode.data.id)
        if (index === 0) {
          this.$alert('当前位置无法上移', '提示', {type: 'warning'})
        } else {
          this.swapArrayItem(this.currentNode.node.parent.data, index, index - 1)
        }
      },
      swapArrayItem (obj, curIndex, preIndex) {
        obj.children[curIndex] = obj.children.splice(
          preIndex,
          1,
          obj.children[curIndex]
        )[0]
        this.$set(obj, 'children', JSON.parse(JSON.stringify(obj.children)))
        this.synch()
      },
      moveDown () {
        let children =
          this.currentNode.node.parent.data.children ||
          this.currentNode.node.parent.data
        let index = children.findIndex(x => x.id === this.currentNode.data.id)
        if (index === this.currentNode.node.parent.data.children.length - 1) {
          this.$alert('当前位置无法下移', '提示', {type: 'warning'})
        } else {
          this.swapArrayItem(this.currentNode.node.parent.data, index, index + 1)
        }
      },
      insertIntoDoc () {
        let nodes = this.$refs.evidenceTree
          .getCheckedNodes()
          .filter(node => Number(node.type) !== 0)

        if (!nodes.length) nodes.push(this.currentNode.data)

        this.$parent.$parent.$refs.docView.insertIntoDoc(nodes)

        this.$refs.evidenceTree.setCheckedNodes([])
      },
      async deleteNode (type) {
        let checkedNodes = []
        if (!type) {
          checkedNodes = getTreeNodes([this.currentNode.data])
        } else if (type === 'file') {
          checkedNodes = this.$refs.evidenceTree
            .getCheckedNodes()
            .filter(node => Number(node.type) === 1 || Number(node.type) === 2)
        } else if (type === 'dir') {
          checkedNodes = this.$refs.evidenceTree.getCheckedNodes()
        } else if (type === 'root') {
          let tree = this.$refs.evidenceTree
          checkedNodes = getTreeNodes(tree.root.data)
        }
        checkedNodes = checkedNodes.filter(item => Number(item.pid) !== -1)

        try {
          if (type !== 'root') await this.$confirm('是否删除?', '提示')
          this.loadStatus({loading: true, loadingText: '删除中...'})
          await this.addRecycleBinData(checkedNodes)
          this.delfun(checkedNodes)
          this.$refs.evidenceTree.setCheckedNodes([])
          await this.synch()
          this.$parent.$parent.$refs.docView.refresh()
        } catch (e) {
          console.error(e)
        } finally {
          this.loadStatus()
        }
      },
      showContextMenu (e, data, node) {
        this.currentNode = {e, data, node}
        let tree = this.$refs.evidenceTree

        this.isRename = false
        let isRoot = node.level === 1
        let isFile = Number(data.type) !== 0
        let isDir = Number(data.type) === 0
        let isMulti = this.$refs.evidenceTree.getCheckedNodes().length > 0
        let isRename = this.isRename
        let isSelect = window.getSelection().toString().length > 0
        let isMedia = /media|audio/i.test(data.fileType) && !isMulti

        if (isMulti) {
          isRoot = false
          isFile = false
          isDir = false
        }
        if (isRename) {
          isMulti = false
          isRoot = false
          isFile = false
          isDir = false
        }

        let contextmenu = [
          // {
          //   label: '预览',
          //   icon: getBase64('/img/catalog/yl.png'),
          //   show: isFile,
          //   click: this.preView
          // },
          {
            label: '使用本地软件播放',
            icon: getBase64('/img/play.png'),
            show: isMedia,
            click: async ev => {
              let fileName = await commonServer.getPDFFileByID(data.fileID)
              const {dir, name} = path.parse(this.casePath)
              let pathStr = path.resolve(dir, name, fileName)
              if (!fs.existsSync(pathStr)) {
                return this.$alert(`文件【${pathStr}】不存在！`, '找不到文件', {
                  type: 'error'
                })
              }
              openDirOrFile(pathStr)
            }
          },
          {
            label: '重命名',
            icon: getBase64('/img/catalog/cmm.png'),
            show: (isDir || isFile) && !isRoot,
            click: this.renameNode
          },
          {
            label: '复制目录',
            icon: getBase64('/img/catalog/cmm.png'),
            show: isDir || isRoot,
            click: this.copyNode
          },
          {
            label: '粘贴目录',
            icon: getBase64('/img/catalog/cmm.png'),
            show: (isDir || isRoot) && this.copyCatalog,
            click: this.pasteNode
          },
          {
            label: '添加子目录',
            icon: getBase64('/img/catalog/02.png'),
            show: isRoot || isDir,
            click: this.addSubNode
          },
          {
            label: '添加章节幻灯片',
            icon: getBase64('/img/catalog/wbwj.png'),
            show: isRoot || isDir,
            click: this.addPage
          },
          {
            label: '添加空白幻灯片',
            icon: getBase64('/img/catalog/tjkby.png'),
            show: isRoot || isDir,
            click: this.addBlankPage
          },
          {
            label: '添加外部文件',
            icon: getBase64('/img/catalog/03.png'),
            show: isRoot || isDir,
            click: () => {
              // if (!process.browser) return this.addFiles()
              let config = {multiple: true}
              config.multiple = config.multiple || false
              config.accept = config.accept || '*/*'

              let input = document.createElement('input')
              input.type = 'file'
              input.multiple = config.multiple
              input.accept = config.accept
              // if (fn) {
              //   console.log('绑定onchange事件')
              input.onchange = this.addFiles
              // }
              input.click()
              // this.openFileDialog(config, this.addFiles)
            }
          },
          {
            label: '上移',
            icon: getBase64('/img/catalog/sy.png'),
            show: (isFile || isDir) && !isRoot,
            click: this.moveUp
          },
          {
            label: '下移',
            icon: getBase64('/img/catalog/xy.png'),
            show: (isFile || isDir) && !isRoot,
            click: this.moveDown
          },
          {
            label: '删除',
            icon: getBase64('/img/catalog/04.png'),
            show: (isFile || isDir) && !isRoot,
            click: async () => {
              await this.deleteNode()
            }
          },
          {
            label: '删除选中文件',
            icon: getBase64('/img/catalog/delfile.png'),
            show: isMulti,
            click: async () => {
              await this.deleteNode('file')
            }
          },
          {
            label: '删除选中目录及文件',
            icon: getBase64('/img/catalog/delfolder.png'),
            show: isMulti,
            click: async () => {
              await this.deleteNode('dir')
            }
          },
          {
            label: '展开全部节点',
            icon: getBase64('/img/catalog/zk.png'),
            show: isRoot || isDir,
            click: this.expandAll
          },
          {
            label: '收拢全部节点',
            icon: getBase64('/img/catalog/sq.png'),
            show: isRoot || isDir,
            click: this.collapseAll
          },
          {
            label: '插入至预案',
            icon: getBase64('/img/catalog/crya.png'),
            show: isRoot,
            click: this.insertCatalog
          },
          {
            label: '插入至预案',
            icon: getBase64('/img/catalog/crya.png'),
            show: isMulti || isFile,
            click: this.insertIntoDoc
          },
          {
            label: '保存为模板',
            icon: getBase64('/img/catalog/saveTemplate.png'),
            show: isRoot,
            click: this.saveTemplate
          },
          {
            label: '初始化',
            icon: getBase64('/img/catalog/csh.png'),
            show: isRoot,
            click: this.initCatalogData
          },
          {
            label: '剪切',
            icon: getBase64('/img/cut.png'),
            show: isRename && isSelect,
            click: ev => document.execCommand('cut', false, null)
          },
          {
            label: '复制',
            icon: getBase64('/img/copy.png'),
            show: isRename && isSelect,
            click: ev => document.execCommand('copy', false, null)
          },
          {
            label: '粘贴',
            icon: getBase64('/img/paste.png'),
            show: isRename,
            click: ev => document.execCommand('paste', false, null)
          },
          {
            label: '导入模板',
            icon: getBase64('/img/paste.png'),
            show: isDir && !isRoot,
            click: async ev => {
              let children = node.data.children || []

              if (children.length) {
                try {
                  await this.$confirm(
                    '导入模板将会删除当前目录所有数据，是否继续？',
                    '提示',
                    {
                      confirmButtonText: '是',
                      cancelButtonText: '否'
                    }
                  )
                  for (let i = 0; i < children.length; i++) {
                    let item = children[i]
                    console.log('移除', item)
                    tree.remove(item)
                    i--
                  }
                } catch (e) {
                  console.log('取消===>导入模板')
                  return
                }
              }

              let datas = []
              let templateData = L.LocalStore.getTemplateData()
              templateData = templateData || []
              let filter = templateData.filter(x => x.default)

              if (filter.length) {
                datas = filter[0].data
              } else {
                let template = JSON.parse(
                  JSON.stringify(this.catalogTemplate.find(x => x.inlay))
                )
                if (template) {
                  datas = template.data
                } else {
                  datas = this.catalogTemplate.length
                    ? JSON.parse(JSON.stringify(this.catalogTemplate[0]))
                    : []
                }
              }
              datas = recursionUpdateIdAndPid(datas)
              datas.forEach(item => {
                item.pid = data.id
                this.append(item, data)
              })
              this.synch()
            }
          },
          {
            label: '移至顶层',
            icon: getBase64('/img/paste.png'),
            show: isFile,
            click: ev => {
              let children = node.parent.data.children
              if (children.length < 2) return this.$alert('无需移动', '提示')
              let _node = JSON.parse(JSON.stringify(data))
              tree.remove(data)
              tree.insertBefore(_node, children[0])
              this.synch()
            }
          },
          {
            label: '移至底层',
            icon: getBase64('/img/paste.png'),
            show: isFile,
            click: ev => {
              let children = node.parent.data.children
              if (children.length < 2) return this.$alert('无需移动', '提示')
              let _node = JSON.parse(JSON.stringify(data))
              let _pnode = JSON.parse(JSON.stringify(node.parent.data))
              tree.remove(data)
              tree.append(_node, _pnode)
              this.synch()
            }
          },
          {
            label: '同步阅卷辅助',
            icon: getBase64('/img/paste.png'),
            show: isRoot && this.$route.name === 'OpenCaseAppearCourt',
            click: this.TBZHGSSJ
          }
        ]

        this.contextMenuShow(e, contextmenu)
      },
      /**
       * 删除节点
       * @param nodes 要删除的节点
       **/
      delfun (nodes = []) {
        let tree = this.$refs.evidenceTree
        nodes.forEach(node => {
          if (tree) tree.remove(node)
          this.clearSlideEditor(node.id)
        })
      },
      windowPointermove (ev) {
        if (ev.pointerType === 'touch') return
        if (this.isRename) return
        ev.returnValue = false

        let el = ev.target

        let inClass = ''

        inClass = el.classList.contains('evidenceCatalogTree')
          ? 'evidenceCatalogTree'
          : ''
        inClass =
          inClass ||
          (el.classList.contains('ckeditor_box_iframe')
            ? 'ckeditor_box_iframe'
            : '')

        if (!inClass) {
          while ((el = el.parentElement)) {
            if (el.classList.contains('evidenceCatalogTree')) {
              inClass = 'evidenceCatalogTree'
              break
            } else if (el.classList.contains('ckeditor_box_iframe')) {
              inClass = 'ckeditor_box_iframe'
              break
            }
          }
        }

        let div = this.$refs.cursor
        let cursorImg = this.$refs.cursor_img
        let x = ev.screenX - window.screenX
        let y = ev.screenY - window.screenY - 10 - (window.outerHeight - window.innerHeight)
        x = x - div.offsetWidth / 2
        div.style.left = `${x}px`
        div.style.top = `${y}px`
        div.style.visibility = `visible`
        if (inClass === 'evidenceCatalogTree') {
          // div.style.backgroundColor = 'blue';
          cursorImg.style.backgroundImage = `url('${getBase64(
            '/img/able.png'
          )}')`
          console.log('在evidenceCatalogTree中')
        } else if (inClass === 'ckeditor_box_iframe') {
          // div.style.backgroundColor = 'red';
          cursorImg.style.backgroundImage = `url('${getBase64(
            '/img/able.png'
          )}')`
          console.log('在编辑器中')
        } else {
          cursorImg.style.backgroundImage = `url('${getBase64(
            '/img/disable.png'
          )}')`
          console.log('都不在')
        }
      },
      async pointerdown (e, data, node) {
        if (e.pointerType === 'touch') return
        if (e.button !== 0) {
          if (e.button === 2) {
            e.stopPropagation()
            this.showContextMenu(e, data, node)
          }
          return
        }
        if (this.isRename) return

        this.isPointerdown = true
        this.isPointerout = false

        let pointerup = ev => {
          ev.stopPropagation()
          this.isPointerdown = false
          this.isPointerout = false
          console.log('pointerup')
          let div = this.$refs.cursor
          div.style.visibility = `hidden`
          this.setTempData()
          this.windowsRemoveEventListener('pointermove', this.windowPointermove)
          this.windowsRemoveEventListener('pointerup', pointerup)
        }
        this.windowsAddEventListener('pointerup', pointerup)
      },
      async pointerout (e, data, node) {
        e.returnValue = false
        if (e.pointerType === 'touch') return

        let el = e.target

        if (!el.classList.contains(`node_${data.id}`)) {
          while ((el = el.parentElement)) {
            if (el.classList.contains(`node_${data.id}`)) break
          }
        }

        el.style['borderTop'] = '0px #8FB9E3 solid'
        el.style['borderBottom'] = '0px #8FB9E3 solid'
        el.style.backgroundColor = null

        if (!this.isPointerdown) return
        if (this.isPointerout) return
        console.log('pointerout')
        this.isPointerout = true

        if (this.isRename) return e.preventDefault()
        let transferData = []
        this.currentNode = {
          event: e,
          data: data,
          parent: node.parent
        }

        transferData = this.$refs.evidenceTree.getCheckedNodes()

        transferData = transferData.filter(x => Number(data.type) === 0 ? Number(x.type) === 0 : Number(x.type) !== 0)
        console.log(transferData)
        if (transferData.length === 0) transferData.push(data)

        if (Number(data.type) === 0) {
          console.log('这是目录')
        } else {
          console.log('这是文件')
        }

        console.log(this.currentNode)
        if (transferData.length === 0) transferData.push(data)

        this.cursor_text = `${transferData.length}个文件`

        this.setTempData({
          type: 'evidence',
          data: JSON.stringify(transferData)
        })

        this.windowsAddEventListener('pointermove', this.windowPointermove)
      },
      async pointermove (e, data, node) {
        if (e.pointerType === 'touch') return
        if (this.isRename) return
        e.returnValue = false

        let type = this.tempData.type

        if (!type) return
        let el = e.target

        if (!el.classList.contains(`node_${data.id}`)) {
          while ((el = el.parentElement)) {
            if (el.classList.contains(`node_${data.id}`)) break
          }
        }

        if (Number(data.type) === 0) {
          if (
            data.pid === '-1' ||
            (e.offsetY > el.offsetHeight / 3 &&
              e.offsetY < el.offsetHeight * 2 / 3)
          ) {
            // 中间1/3
            delBorder('borderTop')
            delBorder('borderBottom')
            el.style.backgroundColor = '#D6EAFE'
          } else if (e.offsetY < el.offsetHeight / 3) {
            // 上面1/3
            addBorder('borderTop')
            delBorder('borderBottom')
          } else {
            // 下面1/3
            addBorder('borderBottom')
            delBorder('borderTop')
          }
        } else {
          if (e.offsetY < el.offsetHeight / 2) {
            addBorder('borderTop')
            delBorder('borderBottom')
          } else {
            addBorder('borderBottom')
            delBorder('borderTop')
          }
        }

        // 添加边框
        function addBorder (topOrBottom) {
          el.style[topOrBottom] = '2px #8FB9E3 solid'
          el.style.backgroundColor = null
        }

        // 取消边框
        function delBorder (topOrBottom) {
          el.style[topOrBottom] = '0px #8FB9E3 solid'
        }
      },
      async pointerup (e, data, node) {
        if (e.pointerType === 'touch') return
        if (e.button !== 0) return
        if (this.isRename) return
        e.returnValue = false

        let el = e.target

        if (!el.classList.contains(`node_${data.id}`)) {
          while ((el = el.parentElement)) {
            if (el.classList.contains(`node_${data.id}`)) break
          }
        }

        let type = this.tempData.type
        if (!type) return
        let nodes = JSON.parse(this.tempData.data)
        let style = this.DefaultBackground
        let template = this.$store.getters.defaultTemplate

        let prePush = []

        if (type === 'juanzong') {
          if (this.isMergeDir) {
            nodes.forEach(item => {
              if (item.FileType === 'dir') return
              let pnode = nodes.find(_item => item.NodeParentID === _item.NodeID)
              if (!pnode) return
              if (pnode.FileType !== 'dir') return
              item.MLXSMC = `${pnode.MLXSMC}(${item.MLXSMC})`
            })
            nodes = nodes.filter(item => item.FileType !== 'dir')
          }
          nodes.forEach(item => {
            item.style = style
            item.template = template
          })
          prePush = getPrePushNodes(nodes)
        } else if (type === 'evidence') {
          // 左边进行排序拖拽
          for (let obj of nodes) {
            // 判断移动的节点是否为释放节点的父节点
            if (isParent(obj, node)) {
              this.pointerout(e, data)
              return
            }
          }

          // 排序是否移动文件夹
          let isMoveDir = nodes.filter(x => Number(x.type) === 0).length > 0

          if (isMoveDir) {
            prePush = nodes.filter(item => {
              for (let obj of nodes) {
                if (item.pid === obj.id) {
                  return false
                }
              }
              return true
            })
          } else {
            if (
              Number(this.currentNode.data.type) === 0 &&
              nodes.length === 1 &&
              nodes[0].id === this.currentNode.data.id
            ) {
              prePush = nodes
            } else {
              prePush = nodes.filter(item => Number(item.type) !== 0)
            }
          }
          this.delfun(prePush)
        }

        // 先判断释放节点为文件节点还是文件加节点 type=0为文件夹
        if (Number(data.type) === 0) {
          // 此处为文件夹节点，文件夹节点，有上中下，三种情况（除根节点）

          if (
            data.pid === '-1' ||
            (e.offsetY > el.offsetHeight / 3 &&
              e.offsetY < el.offsetHeight * 2 / 3)
          ) {
            // 中间1/3
            for (let i = 0; i < prePush.length; i++) {
              let obj = prePush[i]
              obj.pid = data.id
              this.append(obj, data)
            }
          } else if (e.offsetY < el.offsetHeight / 3) {
            // 上面1/3
            for (let i = 0; i < prePush.length; i++) {
              let obj = prePush[i]
              obj.pid = data.pid
              this.insertBefore(obj, data)
            }
          } else {
            // 下面1/3
            prePush = prePush.reverse()
            for (let i = 0; i < prePush.length; i++) {
              let obj = prePush[i]
              obj.pid = data.pid
              this.insertAfter(obj, data)
            }
          }
        } else {
          if (e.offsetY < el.offsetHeight / 2) {
            // 上面1/2
            for (let i = 0; i < prePush.length; i++) {
              let obj = prePush[i]
              obj.pid = data.pid
              this.insertBefore(obj, data)
            }
          } else {
            // 下面1/2
            prePush = prePush.reverse()
            for (let i = 0; i < prePush.length; i++) {
              let obj = prePush[i]
              obj.pid = data.pid
              this.insertAfter(obj, data)
            }
          }
        }

        this.$refs.evidenceTree.setCheckedNodes([])
        this.$emit('clear-checked', 'juanzong')

        this.pointerout(e, data)

        await this.synch()

        this.expandNode(data.id, false)

        /**
         * 判断释放节点是否为拖拽节点的子节点
         * @returns {*}
         * @param obj 要移动的节点
         * @param cNode 当前节点
         */
        function isParent (obj, cNode) {
          // node 为释放的节点
          if (obj.id === cNode.data.pid || obj.id === cNode.data.id) {
            // 如果移动的节点的id===释放节点的pid,则返回true
            return true
          } else if (cNode.parent) {
            // 否则判断当前节点是否有父节点
            return isParent(obj, cNode.parent)
          }
          return false
        }
      },
      append (obj, data) {
        let tree = this.$refs.evidenceTree
        let node = tree.getNode(data)
        if (Number(obj.type) === 0) {
          let sameDir = ''
          if (node.data.alias === obj.alias) {
            sameDir = node.data
          } else {
            let children = node.data.children || []
            sameDir = children.find(item => item.alias === obj.alias)
          }
          if (sameDir) {
            if (obj.children) {
              obj.children.forEach(item => {
                item.pid = sameDir.id
                tree.append(item, sameDir)
              })
            }
            return this.$message('当前目录中已存在相同目录，已自动合并')
          }
        }
        tree.append(obj, node)
      },
      insertBefore (obj, data) {
        let tree = this.$refs.evidenceTree
        let node = tree.getNode(data)
        if (Number(obj.type) === 0 && node.parent) {
          let sameDir = ''
          if (node.parent.data.alias === obj.alias) {
            sameDir = node.parent.data
          } else {
            let children = node.parent.data.children || []
            sameDir = children.find(item => item.alias === obj.alias)
          }
          if (sameDir) {
            if (obj.children) {
              obj.children.forEach(item => {
                item.pid = sameDir.id
                tree.append(item, sameDir)
              })
            }
            return this.$message('当前目录中已存在相同目录，已自动合并')
          }
        }
        tree.insertBefore(obj, node)
      },
      insertAfter (obj, data) {
        let tree = this.$refs.evidenceTree
        let node = tree.getNode(data)
        if (Number(obj.type) === 0 && node.parent) {
          let sameDir = ''
          if (node.parent.data.alias === obj.alias) {
            sameDir = node.parent.data
          } else {
            let children = node.parent.data.children || []
            sameDir = children.find(item => item.alias === obj.alias)
          }
          if (sameDir) {
            if (obj.children) {
              obj.children.forEach(item => {
                item.pid = sameDir.id
                tree.append(item, sameDir)
              })
            }
            return this.$message('当前目录中已存在相同目录，已自动合并')
          }
        }
        tree.insertAfter(obj, node)
      },
      renderContent (h, {node, data, store}) {
        return (
          <span
            class={'word14 node_' + data.id}
            id={data.id}
            style="width:calc(100% - 46px);display: inline-block;height:100%;"
            onPointerup={() => this.pointerup(event, data, node)}
            onPointermove={() => this.pointermove(event, data, node)}
            onPointerout={() => this.pointerout(event, data, node)}
            onPointerdown={() => this.pointerdown(event, data, node)}
          >
            <img
              src={
                (process.browser ? '/static' : __static) + (Number(data.type) === 0 ? '/img/fold.png' : Number(data.type) === 1 ? '/img/fold2.png' : '/img/cover.png')
              }
              style="width:16px;height:16px;padding-right:3px;margin-top:4px;vertical-align: top !important;"
            />
            {
              this.editID === data.id
                ? (
                  <input
                    id={data.id + '_span'}
                    style="border:1px solid #66afe9;outline:none;boxShadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6);cursor:auto;min-width: calc(100% - 60px);display: inline-block;padding-left:3px;height:100%;line-height:26px;vertical-align: top !important;"
                    on-keydown={(e) => this.saveNode(e, data, node)}
                    on-blur={(e) => this.saveNode(e, data, node)}
                    // on-paste={() => this.paste(event, data, node)}
                    // onInput={e => this.changeRenameText(e)}
                    value={data.alias}
                  />
                )
                : (<span
                  id={data.id + '_span'}
                  style="min-width: calc(100% - 60px);display: inline-block;padding-left:3px;height:100%;line-height:26px;vertical-align: top !important;"
                  on-dblclick={() => this.renameNode(event, data, node)}
                >
                  {data.alias}
                </span>)
            }
          </span>
        )
      },
      filterNode (value, data, node) {
        if (!value) return true
        if (node.level > 1 && node.parent.visible) return true
        return data.alias.indexOf(value) !== -1
      },
      _nodeClick (data, node) {
        let tree = this.$refs.test_tree
        console.log('点击了==========', tree.getNode(data))
        console.log('所有选中节点', tree.getCheckedNodes())
        console.log('所有半选中节点', tree.getHalfCheckedNodes())
      },
      nodeClick (data, node, c, ev = event) {
        if (ev && !ev.isTrusted) return
        if (this.isRename) return

        /**
         * 去除所有的子节点
         * @param nodes
         * @param pid
         */
        function clearChildNodeByPid (nodes = [], pid) {
          for (let i = 0; i < nodes.length; i++) {
            let node = nodes[i]
            if (node.pid === pid) {
              if (node.children) {
                clearChildNodeByPid(nodes, node.id)
              }
              nodes.splice(i, 1)
              i--
            }
          }
          return nodes
        }

        /**
         * 获取按住Ctrl时需要勾选的node
         * @param nodes 目前所有选中的节点
         * @param node 需要操作的节点
         * @param cheched 是否选中
         */
        function getCtrlNodes (nodes = [], node, cheched) {
          let index = nodes.findIndex(_node => _node.id === node.id)
          let isExist = index > -1
          if (cheched) {
            if (!isExist) nodes.push(node)
          } else {
            if (isExist) nodes.splice(index, 1)
          }
          return nodes
        }

        /**
         * 获取按住Shift时需要勾选的node
         * @param id1 其中一个ID
         * @param id2 其中一个ID
         * @param treeNodes 数据源
         * @returns {Array}
         */
        let getShiftNodes = (id1, id2, treeNodes = []) => {
          let nodes = []
          console.log('treeNodes', treeNodes)
          let index1 = treeNodes.findIndex(item => item.id === id1)
          let index2 = treeNodes.findIndex(item => item.id === id2)
          if (index2 === -1) index2 = 0
          if (index1 < 0) return nodes
          if (index1 > index2) {
            let temp = index2
            index2 = index1
            index1 = temp
          }
          for (let i = index1; i <= index2; i++) {
            if (
              i !== index2 &&
              treeNodes[i].children &&
              treeNodes[i].children.length
            ) {
              continue
            }
            let isExist =
              nodes.findIndex(item => item.id === treeNodes[i].id) > -1
            if (!isExist) nodes.push(treeNodes[i])
          }
          return nodes
        }

        let tree = this.$refs.evidenceTree // 示证目录树
        let nodes = tree.getCheckedNodes() // 当前所有的选中节点

        if (ev && ev.ctrlKey) {
          this.lastCheckedNode = data
          let p = node
          while ((p = p.parent)) {
            if (p.checked) nodes = nodes.filter(item => item.id !== p.data.id)
          }
          nodes = clearChildNodeByPid(nodes, data.id)
          tree.setCheckedNodes(getCtrlNodes(nodes, data, !node.checked))
          return
        }
        if (ev && ev.shiftKey) {
          tree.setCheckedNodes(
            getShiftNodes(data.id, this.lastCheckedNode.id, this.evidenceCatalog)
          )
          return
        }
        console.log('点击了树节点', node)
        this.$emit('node-click', data, node)
      },
      check (data) {
        this.lastCheckedNode = data
      },
      /**
       * 根据id展开自身及父节点
       */
      expandNode (id, isScroll = true) {
        try {
          console.group('展开节点，并滚动到该节点位置')
          let node = this.$refs.evidenceTree.getNode(id)
          if (!node) return console.log(`未找到id为【${id}】的节点`)
          console.log('已找到要展开的节点', node.data.alias)
          let _node = node
          _node.expand()
          while ((_node = _node.parent)) {
            _node.expand()
          }
          console.log('已展开节点')
          let el = document.querySelector(`#${this.id} .node_${id}`)
          isScroll &&
          this.$nextTick(() => {
            if (el) {
              el.scrollIntoView({
                behavior: 'smooth',
                block: 'nearest',
                inline: 'nearest'
              })
            }
            console.log('滚动到节点位置')
          })
        } finally {
          console.groupEnd()
        }
      },
      setSelectedNode (id) {
        let node = this.getNode(id)
        if (!node) return
        this.expandNode(id)
        let tree = this.$refs.evidenceTree
        if (tree) tree.setCurrentNode(node.data)
        this.nodeClick(node.data, node)
      },
      getNode (id) {
        let tree = this.$refs.evidenceTree
        return tree ? tree.getNode(id) : null
      }
    }
  }
</script>

<style scoped lang="scss">
  .evidenceCatalogTree_box {
    width: 100%;
    height: 100%;

    .evidence_catalog_tree_box {
      height: calc(100% - 30px);
      transition-duration: 600ms;

      &.recycle_bin_expand {
        height: 50%;
      }
    }

    .evidence_catalog_recycle_bin {
      height: 30px;
      transition-duration: 600ms;

      &.recycle_bin_expand {
        height: 50%;

        .title {
          .title_btn {
            background-image: url("~@/assets/img/AppearCourt/arrow-down.png");
          }
        }
      }

      /*font-size: 0;*/
      .title {
        background-color: #f3f8fc;
        height: 30px;
        border-bottom: 1px solid #cedce7;

        .title_text {
          vertical-align: top;
          line-height: 30px;
          font-size: 14px;
          width: calc(100% - 30px);
          display: inline-block;
          height: 100%;
          background-repeat: no-repeat;
          background-position: 5px center;
          text-indent: 25px;
          background-image: url("~@/assets/img/AppearCourt/6_03.png");
        }

        .title_btn {
          display: inline-block;
          width: 30px;
          height: 100%;
          background-repeat: no-repeat;
          background-position: center;
          background-image: url("~@/assets/img/AppearCourt/arrow-up.png");
        }
      }

      .evidence_catalog_recycle_bin_tool {
        height: 30px;
        width: 100%;
        padding-top: 5px;
        /*line-height: 25px;*/
        padding-left: 20px;
        position: relative;

        .btns {
          position: absolute;
          top: 2px;
          right: 20px;

          .btn {
            display: inline-block;
            font-size: 14px;
            padding: 2px 5px 2px 10px;
            text-indent: 15px;
            background-repeat: no-repeat;
            background-position: 5px center;
            background-image: url("~@/assets/img/AppearCourt/clear.png");
            border: 1px solid transparent;

            &:hover {
              background-color: #c7e2f5;
              color: #157ac1;
              border-radius: 5px;
              border-color: #5da9df;
              background-image: url("~@/assets/img/AppearCourt/clear+.png");
            }
          }
        }
      }

      .content {
        height: calc(100% - 60px);
        overflow-y: auto;
        overflow-x: hidden;
        background-color: #f3f8fc;

        .content_item {
          width: 100%;

          &:nth-child(1) {
            .content_item_title {
              border-top: none !important;
            }
          }

          .content_item_title {
            height: 30px;
            border-bottom: 1px solid #ccc;
            border-top: 1px solid #ccc;

            .date {
              display: inline-block;
              font-size: 14px;
              height: 100%;
              padding-top: 5px;
              /*line-height: 25px;*/
              width: calc(100% - 150px);
              /*text-indent: 10px;*/
              padding-left: 20px;
              color: #999;
            }

            .btns {
              margin-top: 2px;
              vertical-align: top;
              display: inline-block;
              margin-left: 10px;

              .btn {
                display: inline-block;
                font-size: 14px;
                padding: 2px 5px 2px 10px;
                text-indent: 15px;
                background-repeat: no-repeat;
                background-position: 5px center;
                background-image: url("~@/assets/img/AppearCourt/clear.png");
                border: 1px solid transparent;

                &:hover {
                  background-color: #c7e2f5;
                  color: #157ac1;
                  border-radius: 5px;
                  border-color: #5da9df;
                  background-image: url("~@/assets/img/AppearCourt/clear+.png");
                }

                &:nth-child(2) {
                  background-image: url("~@/assets/img/AppearCourt/restore.png");

                  &:hover {
                    background-image: url("~@/assets/img/AppearCourt/restore+.png");
                  }
                }
              }
            }
          }

          .evidenceCatalogRecycleBinTree {
            background-color: #f3f8fc;
            margin-top: 10px;
            padding-left: 15px;
            padding-right: 15px;
          }
        }
      }
    }
  }

  .evidenceCatalogTree {
    width: 100%;
    height: calc(100% - 40px);
    overflow-y: auto;
    overflow-x: hidden;
  }

  .contextMenu div img {
    margin-right: 5px;
  }

  .search_box {
    height: 40px;
    width: 100%;
    background-color: #eaf1f7;
    border-bottom: solid 1px #9aadb9;
  }

  .search_input {
    margin: 5px 0 0 10px;
    height: 30px;
    padding: 10px;
    width: calc(100% - 50px);
    border: 1px solid;
  }

  .cursor_div {
    position: fixed;
    width: 100px;
    /*height: 50px;*/
    left: 0;
    top: 0;
    z-index: 999999;
    visibility: hidden;
    pointer-events: none;
    text-align: center;
  }

  .cursor_div .cursor_text {
    font-size: 12px;
    color: white;
    text-align: center;
    background-color: rgba(0, 0, 0, 0.3);
    display: inline-block;
    padding-right: 10px;
    padding-left: 10px;
  }

  .cursor_div .cursor_img {
    height: 16px;
    width: 16px;
    background-size: 14px;
    margin-right: 5px;
    display: inline-block;
    background-position: center;
    background-repeat: no-repeat;
    /*margin-left: 20px;*/
  }
</style>
